package cn.com.lms.business.livecourse.service;

import cn.com.lms.business.core.util.CurrentUserInstance;
import cn.com.lms.business.learning.persistence.repository.LearningPlanRepository;
import cn.com.lms.business.learning.service.LearningPlanService;
import cn.com.lms.business.learning.service.LearningStudentService;
import cn.com.lms.business.livecourse.constant.SysSettingConstant;
import cn.com.lms.business.livecourse.persistence.entity.CourseLiveSign;
import cn.com.lms.business.livecourse.persistence.entity.vo.CourseLiveSignInVo;
import cn.com.lms.business.livecourse.persistence.repository.CourseLiveSignRepository;
import cn.com.lms.business.user.persistence.entity.SysUserVo;
import com.bnzj.core.persistence.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * CourseLiveSignService
 *
 * @author barry
 * @date 2020/3/30
 **/
@Service
public class CourseLiveSignService extends BaseService<CourseLiveSignRepository, CourseLiveSign, Long> {

    @Autowired
    CourseLiveService courseLiveService;

    @Autowired
    LearningPlanService planService;

    /**
     * 直播课程 签到
     *
     * @param courseId      课程id
     * @param planId        学习计划id
     * @param stageDetailId 学习阶段详情id
     * @throws Exception
     */
    @Transactional(rollbackFor = {Exception.class})
    public CourseLiveSignInVo liveCourseSignIn(long courseId, long planId, long stageDetailId) throws Exception {
        SysUserVo sysUser = CurrentUserInstance.getCurrentUser();
        if (null == sysUser) {
            throw new Exception("用户信息异常");
        }

        // 日期时间使用处理
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date startDate = calendar.getTime();    // 今天0点时间

        // 对应阶段详情的今天签到标识
        boolean stageDetailTodayFirstSignIn = true;
        // 查询已有签到信息，获取当前学习计划阶段课程的总学习时长
        List<CourseLiveSign> exists = this.repository.existSigns(stageDetailId, sysUser.getAccount());
        int existsDuration = 0;
        if (null != exists && exists.size() > 0) {
            for (CourseLiveSign item : exists) {
                existsDuration += item.getDuration();
                if (item.getEnterTime().getTime() > startDate.getTime()) {
                    // 已有的签到记录，其签到时间已经存在大于今天0点，设置对应阶段详情的今天签到标识为false
                    stageDetailTodayFirstSignIn = false;
                }
            }
        }

        // 查询今天的总学习时长
        calendar.add(Calendar.DATE, 1);
        Date endDate = calendar.getTime();  // 明天0点时间
        Map queryRe = this.repository.todayTotalDuration(sysUser.getAccount(), startDate, endDate);
        int todayTotalDuration = 0;
        BigDecimal ttd = (BigDecimal) queryRe.get("todayTotalDuration");
        System.out.println("ttd = " + ttd);
        if (null != ttd && 0 != ttd.intValue()) {
            todayTotalDuration = ttd.intValue();
        }

        // 签到
        CourseLiveSign courseLiveSign = new CourseLiveSign();
        courseLiveSign.setAccount(sysUser.getAccount());
        courseLiveSign.setCourseInfoId(courseId);
        courseLiveSign.setPlanId(planId);
        courseLiveSign.setStageDetailId(stageDetailId);
        courseLiveSign.setCname(sysUser.getCname());
        courseLiveSign.setPhone(sysUser.getPhone());
        courseLiveSign.setIdentity(sysUser.getIdentity());
        courseLiveSign.setDeptId(sysUser.getDeptId());
        courseLiveSign.setFullDeptName(sysUser.getFullDeptName());
        courseLiveSign.setEnterTime(new Date());
        courseLiveSign = this.repository.save(courseLiveSign);
        Long id = courseLiveSign.getId();
        if (0 == id) {
            throw new Exception("添加直播课程签到记录失败");
        }

        // 第一次添加签到记录时，增加观看者数
        if (null == exists && 0 == exists.size()) {
            courseLiveService.incrCourseViewersCount(courseId);
        }

        // 获取每天允许最大学时、随机在线打卡时长（防挂机）
        int allowDailyMaxLearnTime = SysSettingConstant.DEFAULT_ALLOW_DAILY_MAX_LEARN_TIME;
        int randomAlertTime = SysSettingConstant.DEFAULT_RANDOM_ALERT_TIME;
        int allowFastForward = SysSettingConstant.DEFAULT_ALLOW_FAST_FORWARD;
        String sysValue = this.repository.sysSettingValue(SysSettingConstant.KEY_ALLOW_DAILY_MAX_LEARN_TIME);
        String sysRandomAlertTime = this.repository.sysSettingValue(SysSettingConstant.KEY_RANDOM_ALERT_TIME);
        String sysAllowFastForward = this.repository.sysSettingValue(SysSettingConstant.KEY_ALLOW_FAST_FORWARD);
        if (!StringUtils.isEmpty(sysValue)) {
            try {
                allowDailyMaxLearnTime = Integer.valueOf(sysValue);
            } catch (Exception e) {
            }
        }
        if (!StringUtils.isEmpty(sysRandomAlertTime)) {
            try {
                randomAlertTime = Integer.valueOf(sysRandomAlertTime);
            } catch (Exception e) {
            }
        }
        if (!StringUtils.isEmpty(sysAllowFastForward)) {
            try {
                allowFastForward = Integer.valueOf(sysAllowFastForward);
            } catch (Exception e) {
            }
        }

        CourseLiveSignInVo vo = new CourseLiveSignInVo();
        vo.setId(id);
        vo.setDuration(existsDuration);
        vo.setTodayTotalDuration(todayTotalDuration);
        vo.setAllowDailyMaxLearTime(allowDailyMaxLearnTime);
        vo.setRandomAlertTime(randomAlertTime);
        vo.setSdTodayFirstSignIn(stageDetailTodayFirstSignIn ? 1 : 0);
        vo.setAllowFastForward(allowFastForward > 0 ? 1 : 0);
        return vo;
    }

    @Autowired
    LearningStudentService learningStudentService;

    @Autowired
    LearningPlanRepository learningPlanRepository;

    /**
     * 直播课程 签出
     *
     * @param signId      签到记录id
     * @param duration    本次签到学习的时长（单位分钟）
     * @param finishState 学习完成状态：0未完成；1完成
     * @throws Exception
     */
    @Transactional(rollbackFor = {Exception.class})
    public long liveCourseSignOut(long signId, int duration, int finishState) throws Exception {
        Optional<CourseLiveSign> signOptional = this.repository.findById(signId);
        CourseLiveSign sign = signOptional.get();
        if (null == sign) {
            throw new Exception("签到信息异常");
        }

        SysUserVo user = CurrentUserInstance.getCurrentUser();
        if (null == user || 0 == user.getId()) {
            throw new Exception("用户信息异常");
        }

        // 更新学生学习记录
        int updateRe = learningStudentService.updateUserLearningInfo(sign.getStageDetailId(), user.getId(), duration, finishState, new Date());
        // 修改学习计划状态为已完成
        planService.updatePlanFinishState(sign.getPlanId());
        if (0 == updateRe) {
            throw new Exception("更新学生学习记录失败");
        }

        // 签出跨日处理
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date morrowDate = calendar.getTime();    // 今天0点时间
        if (null != sign.getEnterTime() && sign.getEnterTime().getTime() / 1000 < morrowDate.getTime() / 1000) {
            // 记录昨天的签出信息
            calendar.add(Calendar.SECOND, -1);
            int result = this.repository.updateSignInfo(signId, 0, calendar.getTime());
            if (0 == result) {
                throw new Exception("记录昨天的签出信息失败");
            }

            // 新增翌日的签到记录
            calendar.add(Calendar.SECOND, 1);
            CourseLiveSign morrowSign = new CourseLiveSign();
            morrowSign.setAccount(sign.getAccount());
            morrowSign.setCname(sign.getCname());
            morrowSign.setPhone(sign.getPhone());
            morrowSign.setIdentity(sign.getIdentity());
            morrowSign.setDeptId(sign.getDeptId());
            morrowSign.setFullDeptName(sign.getFullDeptName());
            morrowSign.setPlanId(sign.getPlanId());
            morrowSign.setStageDetailId(sign.getStageDetailId());
            morrowSign.setCourseInfoId(sign.getCourseInfoId());
            morrowSign.setDuration(duration);
            morrowSign.setEnterTime(calendar.getTime());
            morrowSign.setExitTime(new Date());
            morrowSign = this.save(morrowSign);
            if (null == morrowSign.getId() || 0 == morrowSign.getId()) {
                throw new Exception("新增翌日的签到记录失败");
            }
            return morrowSign.getId();  // 返回翌日记录id
        }

        // 普通记录签出信息
        int result = this.repository.updateSignInfo(signId, duration, new Date());
        if (0 == result) {
            throw new Exception("记录退出直播课程时间失败");
        }
        return signId;  // 返回当前记录id
    }


//    /**
//     * 更新学生学习时长
//     * @param planId 签到记录id
//     * @throws Exception
//     */
//    @Transactional(rollbackFor = {Exception.class})
//    public void updateStudentLearnTime(long planId, long stageDetailId, int duration) throws Exception {
//        int result = this.repository.updateStudentLearnTime(planId, stageDetailId, duration, new Date());
//        if (0 == result) {
//            throw new Exception("记录退出直播课程时间失败");
//        }
//    }
}
